package com.easily.factory.aop;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * cglib代理继承自目标类，所以可以不用接口，但是速度慢于jdk代理
 */
public class CGlibProxy extends ProxyObject implements MethodInterceptor {

    public CGlibProxy(Object targetObject,AopObject aopObject,boolean isAllMethodProxy) {
        super(targetObject,aopObject,isAllMethodProxy);
    }

    // 代理方法
    // 调用原始方法的几种方式：proxy 是代理类、method 原始方法、args 原始方法参数、methodProxy 代理方法
    // method.invoke(target, args)
    // methodProxy.invoke(target, args)
    // methodProxy.invokeSuper(proxy, args)

    // 拿目标类 target -> 生成代理类 proxy
    // 在调用代理类时，intercept()方法被执行
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        return this.proxyInvoke(method,args, () -> methodProxy.invokeSuper(proxy, args));
    }

    @Override
    public <T> T getProxy(Class<T> z) {
        // 创建代理对象
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.targetObject.getClass());
        // 设置回调用对象为本身，调用对象必须实现接口 MethodInterceptor 中的 intercept()
        enhancer.setCallback(this);
        return z.cast(enhancer.create());
    }
}
